package com.sprite.utils;

/**
 * @author Jack
 */
public final class UtilClass {

    /**
     * check class can be loaded
     *
     * @param className
     *         Class Name
     * @return true if class can be loaded
     */
    public static boolean isPresent(String className) {
        try {
            Class.forName(className);
        } catch (Exception e) {
            return false;
        }

        return true;
    }

    /**
     * load class by class name
     *
     * @param className
     *         The class name
     * @param <T>
     *         泛型
     * @return The class
     */
    @SuppressWarnings("unchecked")
    public static <T> Class<T> forName(String className) {
        try {
            return (Class<T>) Class.forName(className);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 判断类型是否是 基础类型的包装类
     *
     * @param clazz
     *         Class
     * @return true
     * @see java.lang.Boolean
     * @see java.lang.Character
     * @see java.lang.Byte
     * @see java.lang.Short
     * @see java.lang.Integer
     * @see java.lang.Long
     * @see java.lang.Float
     * @see java.lang.Double
     * @see java.lang.Void
     * @since 1.2.5
     */
    public static boolean isPrimitiveTypeWrapClass(Class clazz) {
        if (Boolean.class.isAssignableFrom(clazz) ||
                Character.class.isAssignableFrom(clazz) ||
                Byte.class.isAssignableFrom(clazz) ||
                Short.class.isAssignableFrom(clazz) ||
                Integer.class.isAssignableFrom(clazz) ||
                Long.class.isAssignableFrom(clazz) ||
                Float.class.isAssignableFrom(clazz) ||
                Double.class.isAssignableFrom(clazz) ||
                Void.class.isAssignableFrom(clazz)) {
            return true;
        }

        return false;
    }

    /**
     * 获取基础类型包装类对应的 基础类型描述
     *
     * @param clazz
     *         primitive type
     * @return class represents a primitive type
     * @see java.lang.Boolean#TYPE
     * @see java.lang.Character#TYPE
     * @see java.lang.Byte#TYPE
     * @see java.lang.Short#TYPE
     * @see java.lang.Integer#TYPE
     * @see java.lang.Long#TYPE
     * @see java.lang.Float#TYPE
     * @see java.lang.Double#TYPE
     * @see java.lang.Void#TYPE
     * @since 1.2.5
     */
    public static Class getPrimitiveClassOfPrimitiveTypeWrapClass(Class clazz) {
        if (Boolean.class.isAssignableFrom(clazz)) {
            return Boolean.TYPE;
        }

        if (Void.class.isAssignableFrom(clazz)) {
            return Void.TYPE;
        }

        if (Double.class.isAssignableFrom(clazz)) {
            return Double.TYPE;
        }

        if (Float.class.isAssignableFrom(clazz)) {
            return Float.TYPE;
        }

        if (Long.class.isAssignableFrom(clazz)) {
            return Long.TYPE;
        }

        if (Integer.class.isAssignableFrom(clazz)) {
            return Integer.TYPE;
        }
        if (Byte.class.isAssignableFrom(clazz)) {
            return Byte.TYPE;
        }
        if (Character.class.isAssignableFrom(clazz)) {
            return Character.TYPE;
        }

        return null;
    }

    /**
     * 判断对象是否Bean
     * <p>如下情况不是：</p>
     * <p>1、继承了 Number</p>
     * <p>2、继承了 CharSequence</p>
     * <p>3、基础类型的type，如：Integer.TYPE	， Long.TYPE</p>
     *
     * @param clazz
     *         Class
     * @return true is class is bean
     * @since 1.2.5
     */
    public static boolean isBean(Class<?> clazz) {
        if (Number.class.isAssignableFrom(clazz) || CharSequence.class.isAssignableFrom(clazz)) {
            return false;
        }

        if (clazz.isPrimitive()) {
            return false;
        }

        return true;
    }
}
